package generics;

import java.util.ArrayList;
import java.util.List;

/**
 * @since Oct 13, 2017
 * PECS: producer-extends, consumer-super.
 * https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java
 */
public class ExtendsAndSuper {

    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
        for (int i = 0; i < src.size(); i++)
            dest.set(i, src.get(i));
    }

    public static void main(String[] args) {
        /**
         * extend
         * determine the higher bound of generics
         */
        List<? extends Number> list1 = new ArrayList<Integer>();
        //[error]: add(capture<? extends java.lang.Number>) in List cannot be applied to (java.lang.Integer)
        //[reason]: List<? extends Number> we can call it "Has any list of types inherited from Number",
        //          but it isn't mean that the List can hold any type from Number.
        //          If we can add different types from Number, how can we use it? That's why in theory.
        //          In method add from ArrayList.java we can see that add(E e), the E is <? extents Number> here. That's why in code.
        //list1.add(new Integer(1));

        /**
         * super
         * determine the lower bound of generics
         */
        List<? super Number> list2 = new ArrayList<Object>();
        //[reason]: List<? super Number> means List hold types from Number or base class of Number
        //          We can only add the class inherited from Number because List could be pointer to ArrayList<Number>
        list2.add(new Integer(1));
        list2.add(new Double(1.2));


    }
}
